home *** CD-ROM | disk | FTP | other *** search
/ Aminet 50 / Aminet 50 (2002)(GTI - Schatztruhe)[!][Aug 2002].iso / Aminet / text / edit / tecoc-146.lha / squ.tes < prev    next >
Text File  |  1991-07-11  |  64KB  |  1,774 lines

  1. !SQU.TEC V40.00!
  2. ! --------------------------------------------------------------------- !
  3. !                                    !
  4. ! TECO macro to squish other TECO macros.  This macro will take a nice,    !
  5. ! readable TECO macro and squish it so that it is as small and as fast    !
  6. ! as possible (and is completely unreadable).                !
  7. !                                    !
  8. ! Command line:                                !
  9. !                                    !
  10. !    MUNG SQU OUTFILE[.TEC]=INFILE[.TES]/SWITCHES            !
  11. !                                    !
  12. ! For example:                                !
  13. !                                    !
  14. !    MUNG SQU SQU.TEC=SQU.TES/D:N/L:Y/B:Y/T:Y/C:Y/W:N/A:Y/E:N    !
  15. !                                    !
  16. ! Switches:                                !
  17. !                                    !
  18. !    /D    Delete lexical CR/LFs                    !
  19. !    /L    Set line lengths                    !
  20. !    /B    Delete blank lines                    !
  21. !    /T    Delete lexical TAB/FFs                    !
  22. !    /C    Delete comments                        !
  23. !    /W    Watch progress                        !
  24. !    /A    Automatic mode (ie: squish macros loaded w/^U)        !
  25. !    /E    Allow adjacent ESCapes                    !
  26. !                                    !
  27. ! Use of Q-registers:                            !
  28. !                                    !
  29. !    A.str = macro to run the squish macro in Z; then, if /L is set, !
  30. !    post-process the squished macro so each line is no longer the    !
  31. !    length set by /L:nn.                        !
  32. !                                    !
  33. !    B.num = TRUE if any command line switches were present.        !
  34. !                                    !
  35. !    C.num = the buffer pointer while squishing things for error    !
  36. !    reporting purposes.                        !
  37. !                                    !
  38. !    C.str = the set of comment delimiter characters    (/C:set, or    !
  39. !    <SP><TAB> for /C:Y).                        !
  40. !                                    !
  41. !    E.str = macro telling when to break out of squish loop.  either    !
  42. !    on end of file or end of sub-squish loop            !
  43. !                                    !
  44. !    F.str = SQU initialization and termination macro.        !
  45. !                                    !
  46. !    H.num = TRUE (-1) if we are allowing adjacent escapes (/E:Y)    !
  47. !                                    !
  48. !    K.str = the "non-squishable ^U command" character set (/A:set)    !
  49. !    If we run into a @^Q<delim>text<delim>, and <delim> is *not*    !
  50. !    in the "non-squishable ^U command" character set, we'll assume    !
  51. !    that "text" is a macro that we have to recursively squish.    !
  52. !                                    !
  53. !    O.num = the maximum line width (/L:nn, or 70 for /L)        !
  54. !                                    !
  55. !    P.str = ???P is cleared if abort-on-error bit is set, and it is    !
  56. !    executed as a macro during cleanup, but I don't see where it is    !
  57. !    loaded anywhere.                        !
  58. !                                    !
  59. !    Q.str = used to contain responses from the user.        !
  60. !                                    !
  61. !    R.str = "get-response-from-user" macro.                !
  62. !                                    !
  63. !    S.num, T.num, U.num = used to store the start and end of text    !
  64. !    arguments to TECO commands like FStext1$text2$.            !
  65. !                                    !
  66. !    W.str = "-1W" scope refresh command if watching progress (/W:Y)    !
  67. !                                    !
  68. !    Z.str = SQU macro proper                    !
  69. !                                    !
  70. !    1.num = TRUE (-1) if the following command is @-sign modified    !
  71. !                                    !
  72. !    8.str = a string containing potential delimiting characters    !
  73. !    in case we can't use ESC as a delimiter.  this string will be    !
  74. !    searched for a delimiting character which is not in the string    !
  75. !    we are trying to delimit.                    !
  76. !                                    !
  77. !    9.str = a mask containing labels we'll use in a goto.  Each    !
  78. !    character in the mask corresponds with a TECO command character    !
  79. !    and controls some action the squisher takes when it runs into    !
  80. !    that TECO command.  For example, if the squisher runs into    !
  81. !    <NUL>, the squisher uses the first character in the 9.str mask    !
  82. !    as a label to goto which handles <NUL>'s.  The mask characters    !
  83. !    are:                                !
  84. !                                    !
  85. !        1    command takes character argument        !
  86. !        A    ^A command                    !
  87. !        B    delete if line is blank                !
  88. !        D    delete character from output            !
  89. !        E    E command                    !
  90. !        F    F command                    !
  91. !        L    lowercase char (convert to uppercase)        !
  92. !        O    optionally delete character from output        !
  93. !        T    TAB char                    !
  94. !        U    ^U command                    !
  95. !        V    ^^ command, leave next char as is        !
  96. !        Z    ^Z command, convert to <CARET>-Z        !
  97. !        ^    (caret) next char is really CTRL-char        !
  98. !        $    command takes string argument(s)        !
  99. !        .    (dot) pass character through w/o squishing    !
  100. !        @    the next command is '@' modified        !
  101. !                                    !
  102. ! Changes:                                !
  103. !                                    !
  104. !    Nov-89                                !
  105. !    added comments                            !
  106. !     changed system specific "n,Stext$" to generic "m,nFBtext$"    !
  107. ! --------------------------------------------------------------------- !
  108.  
  109. ! --------------------------------------------------------------------- !
  110. ! Load Q-register F with SQU initialization macro.  This macro loads    !
  111. ! other macros into various Q-registers and handles the command    line    !
  112. ! switches:   either taking them from the command line in the edit    !
  113. ! buffer or prompting the user for them.  When this macro is done,      !
  114. ! SQU will be poised to run and the only thing left in the edit buffer    !
  115. ! will be the input and output filenames.                !
  116. ! --------------------------------------------------------------------- !
  117.  
  118. ^UF            ! F.str = initialization macro            !
  119. ^D            ! set radix to decimal                !
  120. 0ED            ! zero edit mode flag                !
  121. 0^X            ! zero search mode flag                !
  122. ET&128"N        ! if abort-on-error bit is not zero        !
  123.     0,0XP        !   clear P.str                    !
  124. '            ! endif                        !
  125. 0,128ET            ! turn on abort-on-error bit            !
  126. J            ! jump to beginning of edit buffer        !
  127. < @FS%^ES%%; >        ! zap multiple spaces and tabs in edit buffer    !
  128. J            ! jump to beginning of edit buffer        !
  129. :@S%/%            ! search for '/' command line switch delimiter    !
  130. UB            ! put search success into B.num            !
  131. QB"T            ! if there are switches                !
  132.     ET&64"E        !   if not detached                !
  133.         @^A%
  134. %            !     display <CR><LF>                !
  135.     '        !   endif                    !
  136. '            ! endif                        !
  137.  
  138. ! --------------------------------------------------------------------- !
  139. ! Load Q-register R with a "get-response-from-user" macro.        !
  140. !                                    !
  141. ! Entry:                                !
  142. !    The last inserted string is the display prompt.            !
  143. !                                    !
  144. !    The top of the stack is the Q-register name we will return    !
  145. !    the response in.  If the high bit of the Q-register name    !
  146. !    is set, insist on ESC to terminate the response, otherwise    !
  147. !    allow the response to be terminated with CR-LF .        !
  148. !                                    !
  149. ! Returns:                                !
  150. !    Input string in the Q-register you specified on entry.        !
  151. ! --------------------------------------------------------------------- !
  152.  
  153. @^UR\            ! R.str = response macro             !
  154. [0 [1 [2 [3        ! save Q-reg's 0 through 3            !
  155. +0U3            ! 3.num = Q-reg name on top of stack        !
  156. ^YX0            ! 0.str = display prompt (last inserted string)    !
  157. ^YK            ! kill display prompt from edit buffer        !
  158. .U1            ! 1.num = current buf ptr            !
  159. ZJ            ! jump to buf end                !
  160. .U2            ! 2.num = current end of buffer            !
  161. Q3&127"R        ! if Q-reg name in 3.num is alphanumeric    !
  162.             !   it's a valid Q-reg name            !
  163. |            ! else (Q-reg name not alphanumeric)        !
  164.             !   it's not a valid Q-reg name            !
  165.     @^A%?Invalid Q-register in INPLIN
  166. %            !   display error message            !
  167.     @O!EXIT!    !   go down to EXIT                !
  168. '
  169.  
  170. ! --------------------------------------------------------------------- !
  171. ! build a mini-macro in Q-reg 1 which will put the user's response    !
  172. ! into the Q-reg we are using to return the user's response in.        !
  173. ! --------------------------------------------------------------------- !
  174.  
  175. @I%Q2,.X%        ! insert "Q2,.X" into edit buffer        !
  176. Q3&127@I%%        ! insert Q-reg name we're loading response in    !
  177. Q2,.X1            ! put this mini-macro into 1.str        !
  178. Q2,.K            ! and kill it                    !
  179.  
  180. ! --------------------------------------------------------------------- !
  181. ! display the prompt on a new, clean, line                !
  182. ! --------------------------------------------------------------------- !
  183.  
  184. !PROMPT!
  185.  
  186. 13^T            ! display <CR>                    !
  187. ET&512"N        ! if scope, clear to end of screen        !
  188.     0,1ET        !   inhibit type-out conversions        !
  189.     27^T        !   display ESCAPE                !
  190.     1,0ET        !   enable type-out conversions            !
  191.     0:W-4"E        !   if VT100 in ANSI mode            !
  192.         ^^[^T    !     display [                    !
  193.     '        !   endif                    !
  194.     ^^J^T        !   display J                    !
  195. |            ! else (not scope)                !
  196.     10^T        !   display <LF>                !
  197. '            ! endif                        !
  198. .-Q2+(0^Q)"G        ! if anything on current line            !
  199.     0T        !   display it                    !
  200. |            ! else                        !
  201.     :G0        !   display prompt in 0.str            !
  202.     Q2,ZT        !   plus what we've entered so far        !
  203. '            ! endif                        !
  204.  
  205. ! --------------------------------------------------------------------- !
  206. ! Read characters from the console & insert them into the edit buffer.    !
  207. !                                    !
  208. !    DEL            delete last char entered        !
  209. !    ^U            delete everything entered        !
  210. !    ^R            redisplay prompt & what's been entered    !
  211. !    ^Z            delete everything entered and return    !
  212. !    <CR>, <LF>, <ESC>    terminate input                !
  213. ! --------------------------------------------------------------------- !
  214.  
  215. !GETCH!
  216.  
  217. ^TU0            ! get char from console & put in 0.num        !
  218. Q0-127"E        ! if char is DEL                !
  219.     Z-Q2"N        !   if anything has been added to buffer    !
  220.         -D    !     delete last char                !
  221.     '        !   endif                    !
  222.     @O!PROMPT!    !   go up to PROMPT                !
  223. '            ! endif                        !
  224. Q0-21"E            ! if char is ^U                    !
  225.     Q2,ZK        !   kill everything we've entered up to now    !
  226.     @O!PROMPT!    !   go up to PROMPT                !
  227. '            ! endif                        !
  228. Q0-18"E            ! if char is ^R                    !
  229.     13^T        !   display <CR>                !
  230.     10^T        !   display <LF>                !
  231.     :G0        !   display prompt in 0.str            !
  232.     Q2,ZT        !   display everything we've entered up to now    !
  233.     @O!GETCH!    !   go up to GETCH                !
  234. '            ! endif                        !
  235. Q0-26"E            ! if char is ^Z                    !
  236.     Q2,ZK        !   kill everything we've entered up to now    !
  237.     %0^[        !   convert ^Z (1Ah) to <ESC> (1Bh)        !
  238. '            ! endif                        !
  239. Q0-27"E            ! if char is <ESC>                !
  240.     13^T        !   display <CR>                !
  241.     10^T        !   display <LF>                !
  242.     @O!DONE!    !   go down to DONE                !
  243. '            ! endif                        !
  244. Q3&128"E        ! if hi-bit of return Q-reg name is zero    !
  245.     Q0-10"E        !   if char is <LF>                !
  246.         13^T    !     display <CR>                !
  247.         @O!DONE! !    go down to DONE                !
  248.     '        !   endif                    !
  249.     Q0-13"E        !   if char is <CR>                !
  250.         ^T^[    !      suck up <LF> of <CR>-<LF> pair?        !
  251.         @O!DONE! !     go down to DONE                !
  252.     '        !   endif                    !
  253. '            ! endif                        !
  254. Q0@I%%            ! insert input char into edit buffer        !
  255. @O!GETCH!        ! go up to GETCH to get next character        !
  256.  
  257. !DONE!
  258.  
  259. M1            ! execute mini-macro to load Q-reg w/response    !
  260. Q2,.K            ! kill everything we added to the input buffer    !
  261.  
  262. !EXIT!
  263.  
  264. Q1J            ! jump back to where we were before we started    !
  265. ]3 ]2 ]1 ]0        ! restore Q-reg's 0 through 3            !
  266. \            ! end of ^UR                    !
  267.  
  268. ! --------------------------------------------------------------------- !
  269. ! Done loading response macro into Q-register R                !
  270. ! --------------------------------------------------------------------- !
  271.  
  272. ! --------------------------------------------------------------------- !
  273. ! Check for command line switches.  Basically, each switch is searched    !
  274. ! for in the edit buffer:                        !
  275. !                                    !
  276. !    If the switch is not found                    !
  277. !        If there were other switches on the command line    !
  278. !            Set the switch to its default value        !
  279. !        else                            !
  280. !            Prompt the user for the value of the switch    !
  281. !    else                                !
  282. !        If switch followed by ":argument"            !
  283. !            Set switch to "argument"            !
  284. !        else                            !
  285. !            Set switch to the opposite of its default    !
  286. !                                    !
  287. ! While we are checking for switches, we will be building the mask in    !
  288. ! Q-register 9                                !
  289. ! --------------------------------------------------------------------- !
  290.  
  291. ! --------------------------------------------------------------------- !
  292. ! Check for /D "Delete CR/LF" switch.  /D will delete all lexical CR's    !
  293. ! and LF's.  /D:N is the default.  The format for the /D switch is:    !
  294. ! /D:Y or /D:N.  /D just by itself is the same as /D:Y.            !
  295. !                                    !
  296. ! A problem with /D:Y is that the output will probably be all on one    !
  297. ! line.  If you want to delete all CR's and LF's, yet keep the output    !
  298. ! width manageable, use /L:nn.                        !
  299. ! --------------------------------------------------------------------- !
  300.  
  301. 0,0X9                    ! clear mask in 9.str        !
  302. J                    ! jump to beginning of buffer    !
  303. :@FS%/D%%"S                ! if "/D" found            !
  304.     ::@FS%:%%"S            !   if ":arg" found        !
  305.         0A@^UQ%%        !     Q.str = arg        !
  306.         D            !     delete arg        !
  307.     |                !   else (":" not found)    !
  308.         @^UQ%Y%            !     Q.str = "Y"        ! 
  309.     '                !   endif            !
  310. |                    ! else ("/D" not found)        !
  311.     QB"T                !   if any other switches    !
  312.         @^UQ%%            !      Q.str = ""        !
  313.     |                !   else            !
  314.         @I%Delete CR/LF (Y/N) <N>? %
  315.         ^^QMR            !     ask for /D value        !
  316.     '                !   endif            !
  317. '                    ! endif                !
  318. 0QQ"A                    ! if /D val is alphabetic    !
  319.     0QQ&95-^^Y"E            !   if it's 'y' or 'Y'        !
  320.  
  321.         ! load 9.str with labels for control chars, with <LF>,    !
  322.         ! <CR>, and <SP> marked as D.                !
  323.         !                            !
  324.         !   %@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ %            !
  325.         @^U9%DA.......TD..D.......U....Z...V.D%
  326.  
  327.     '                !   endif            !
  328. '                    ! endif                !
  329.  
  330. ! --------------------------------------------------------------------- !
  331. ! Check for /L    "Set line lengths" switch.  If you're not explicitly    !
  332. ! deleting all CR/LF's (ie: /D:N), you can still delete CR/LF's which    !
  333. ! are unecessary yet still keep the width of the output line manageable.!
  334. ! The format of the /L switch is: /L, /L:Y, /L:N, or /L:nn where nn is    !
  335. ! the line length.  /L just by itself is the same as /L:Y, and /L:Y is    !
  336. ! the same as /L:70.   If /D is Y then any /L is ignored.        !
  337. !                                    !
  338. ! Note: the /L switch does delete all lexical CR/LF's; but, after    !
  339. ! everything is squished, goes back and inserts CR/LF wherever needed    !
  340. ! so the maximum width of the output line doesn't exceed nn chars.    !
  341. ! --------------------------------------------------------------------- !
  342.  
  343. !BADNUM!                ! label to re-ask if :nn bad    !
  344. 0UO                    ! clear O.num            !
  345. :Q9"N                    ! if we had /D:Y above        !
  346.     J                !   jump to beginning of buf    !
  347.     :@FS%/L%%"S            !   if "/L" found, delete it    !
  348.         @^A"%/L specified with /D, /L ignored
  349. "                    !     and warn the user     !
  350.         ::@FS%:%%"S        !     if ":arg" found, kill ":"    !
  351.             0A"D        !       if arg is numeric    !
  352.                 < D .-Z; 0A"D > '    ! delete nn    !
  353.             |        !       else            !
  354.                 D    !         delete arg        !
  355.             '        !       endif            !
  356.         '            !     endif            !
  357.     '                !   endif            !
  358. |                    ! else (no /D:Y above)        !
  359.     J                !   jump to beginning of buf    !
  360.     :@FS%/L%%"S            !   if "/L" found        !
  361.         ::@FS%:%%"S        !     if ":arg" found        !
  362.             0A@^UQ%%    !       Q.str = arg        !
  363.             0A"D        !       if arg is numeric    !
  364.                 < D .-Z; 0A"D 0A:@^UQ%% > ' ! get nn    !
  365.             |        !       else            !
  366.                 D    !         delete arg        !
  367.             '        !       endif            !
  368.         |            !     else, just /L        !
  369.             @^UQ%Y%        !       Q.str = "Y"        !
  370.         '            !     endif            !
  371.     |                !   else            !
  372.         QB"T            !     if any other switches    !
  373.             @^UQ%%        !       Q.str = ""        !
  374.         |            !     else            !
  375.             @I%Set line lengths (Y for 70, N, or length) <N>? %
  376.             ^^QMR        !       ask for /L value    !
  377.         '            !     endif            !
  378.     '                !   endif            !
  379.     0QQ"A                !   if /L val is alphabetic    !
  380.         0QQ&95-^^Y"E        !     if it's 'y' or 'Y'    !
  381.  
  382.             ! load 9.str with labels for control chars,    !
  383.             ! with <LF>, <CR>, and <SP> marked as O.    !
  384.             !                        !
  385.             !   %@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ %        !
  386.             @^U9%DA.......TO..O.......U....Z...V.O%
  387.  
  388.             70UO        !       set line length to 70    !
  389.         '            !     endif            !
  390.     '                !   endif            !
  391.     0QQ"D                !   if /L val is numeric    !
  392.         .UQ            !     save current buf ptr    !
  393.         ZJ            !     jump to buf end        !
  394.         GQ            !     put /L str in buffer    !
  395.         ^SC            !     go back to /L str begin    !
  396.         \UO            !     put str value in O.num    !
  397.         ^SD            !     and delete str        !
  398.         .-Z"N            !     if anything left over    !
  399.             ZK        !        kill chars \ skipped    !
  400.             QQJ        !        jump back to old cp    !
  401.             @O!BADNUM!    !        bad number        !
  402.         '            !      endif            !
  403.         QQJ            !      jump back to old cp    !
  404.         QO"E            !      if /L arg is 0        !
  405.             @O!BADNUM!    !        bad number        !
  406.         '            !      endif            !
  407.  
  408.         ! load 9.str with labels for control chars, with <LF>,    !
  409.         ! <CR>, and <SP> marked as O.                !
  410.         !                            !
  411.         !   %@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ %            !
  412.         @^U9%DA.......TO..O.......U....Z...V.O%
  413.  
  414.     '                !   endif            !
  415. '                    ! endif                !
  416.  
  417. ! --------------------------------------------------------------------- !
  418. ! Check for /B "Delete blank lines" switch                !
  419. ! --------------------------------------------------------------------- !
  420.  
  421. :Q9"N                    ! if we had /D:Y above        !
  422.     J                !   jump to beginning of buf    !
  423.     :@FS%/B%%"S            !   if "/B" found        !
  424.         ::@FS%:%%"S        !     if ":arg" found        !
  425.             0A-^^N"E    !       if "/B:N", ignore it    !
  426.                 @^A"%/B:N specified with /D or /L, /B:N ignored
  427. "                    !         warn user        !
  428.             '        !       endif            !
  429.             D        !       delete arg        !
  430.         '            !     endif            !
  431.     '                !   endif            !
  432. |                    ! else    (no /D:Y above)        !
  433.     J                !   jump to beginning of buf    !
  434.     :@FS%/B%%"S            !   if "/B" found        !
  435.         ::@FS%:%%"S        !     if ":arg" found        !
  436.             0A@^UQ%%    !        Q.str = arg        !
  437.             D        !        delete arg        !
  438.         |            !     else            !
  439.             @^UQ%Y%        !        Q.str = "Y"        !
  440.         '            !     endif            !
  441.     |                !   else            !
  442.         QB"T            !     if any other switches    !
  443.             @^UQ%%        !        Q.str = ""        !
  444.         |            !     else            !
  445.             @I%Delete blank lines (Y/N) <N>? %
  446.             ^^QMR        !       ask for /B value    !
  447.         '            !     endif            !
  448.     '                !   endif            !
  449.     0QQ"A                !   if /B val is alphabetic    !
  450.         0QQ&95-^^Y"E        !     if it's 'y' or 'Y'    !
  451.  
  452.             ! load 9.str with labels for control chars,    !
  453.             ! with <LF> marked as B and <SP> marked as D.    !
  454.             !                        !
  455.             !   %@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ %        !
  456.             @^U9%DA.......TB..........U....Z...V.D%
  457.  
  458.         '            !     endif            !
  459.     '                !   endif            !
  460. '                    ! endif                !
  461.  
  462. ! --------------------------------------------------------------------- !
  463. ! at this point, if we've specified /D, /L, or /B above, 9.str should    !
  464. ! hold the labels for the control characters, if it doesn't, we'll    !
  465. ! supply the default labels which only deletes <NUL> and <SP>.        !
  466. !                                    !
  467. ! Note:  we only have entries for <NUL> to <SP> here.  The entry for    !
  468. ! exclamation point will be put in by the /C checking code below.  All    !
  469. ! other entries are appended to 9.str after switch parsing is finished.    !
  470. ! --------------------------------------------------------------------- !
  471.  
  472. :Q9"E                    ! if 9.str is empty        !
  473.     !   %@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ %                !
  474.     @^U9%DA.......T...........U....Z...V.D%    ! load default mask    !
  475. '                    ! endif                !
  476.  
  477. ! --------------------------------------------------------------------- !
  478. ! Check for /T "Delete lexical TABs and FFs" switch.  The format of    !
  479. ! the /T switch is: /T, /T:Y, /T:N.  /T by itself is the same as /T:Y.    !
  480. ! If TABs are used to format the macro to be squished, instead of being !
  481. ! used to start an insert, you'll have to delete them using /T:Y    !
  482. ! --------------------------------------------------------------------- !
  483.  
  484. J                    ! jump to beginning of buffer    !
  485. :@FS%/T%%"S                ! if "/T" found            !
  486.     ::@FS%:%%"S            !   if ":arg" found        !
  487.         0A@^UQ%%        !     Q.str = arg        !
  488.         D            !     delete arg        !
  489.     |                !   else            !
  490.         @^UQ%Y%            !     Q.str = "Y"        !
  491.     '                !   endif            !
  492. |                    ! else                !
  493.     QB"T                !   if any other switches    !
  494.         @^UQ%%            !     Q.str = ""        !
  495.     |                !   else                     !
  496.         @I%Delete lexical TABs and FORM FEEDs (Y/N) <N>? %
  497.         ^^QMR            !     ask for /T value        !
  498.     '                !   endif            !
  499. '                    ! endif                !
  500. 0QQ"A                    ! if /T val is alphabetic    !
  501.     0QQ&95@^UQ%%            !   force it to uppercase    !
  502. '                    ! endif                !
  503.  
  504. ! --------------------------------------------------------------------- !
  505. ! if /T is "Y", the following code takes the existing control char    !
  506. ! mask in Q-reg 9 and replaces the TAB and FF entries with "O".  The    !
  507. ! new control char mask is then put back in Q-reg 9.            !
  508. ! --------------------------------------------------------------------- !
  509.  
  510. 0QQ-^^Y"E                ! if /T is 'Y'            !
  511.     J                !  jump to beginning of buffer    !
  512.     G9                !  load mask into edit buffer    !
  513.     9J                !  jump to TAB entry        !
  514.     D                !  delete existing entry    !
  515.     @I%O%                !  insert "O"            !
  516.     12J                !  jump to FF entry        !
  517.     D                !  delete existing entry    !
  518.     @I%O%                !  insert "O"            !
  519.     J                !  jump to beginning of buffer    !
  520.     0,33X9                !  put mask back in 9.str    !
  521.     0,33K                !  and clean up edit buffer    !
  522. '                    ! endif                !
  523.  
  524. ! --------------------------------------------------------------------- !
  525. ! Check for /C "Delete comments" switch.  This switch deletes comments    !
  526. ! as opposed to labels.  It is easier if comments are distinguishable    !
  527. ! from labels by having a special delimiting character immediately    !
  528. ! following the initial exclamation point.  The format of the /C    !
  529. ! switch is:  /C, /C:Y, /C:N, or /C:? where ? is the special comment    !
  530. ! delimiting character.  /C is the same as /C:Y, and /C:Y implies that    !
  531. ! SPACE and TAB are the special comment delimiters.  When done, Q-reg    !
  532. ! C will contain the special comment delimiting characters.        !
  533. ! --------------------------------------------------------------------- !
  534.  
  535. @^UC%%                    ! C.str = ""            !
  536. J                    ! jump to beginning of buffer    !
  537. :@FS%/C%%"S                ! if "/C" found            !
  538.     ::@FS%:%%"S            !   if ":arg" found        !
  539.         0A@^UQ%%        !     Q.str = arg        !
  540.         D            !     delete arg        !
  541.     |                !   else            !
  542.         @^UQ%Y%            !     Q.str = "Y"        !
  543.     '                !   endif            !
  544. |                    ! else                !
  545.     QB"T                !   if any other switches    !
  546.         @^UQ%%            !     Q.str = ""        !
  547.     |                !   else            !
  548.         @I%Delete comments (Y for SP/TAB, N, or set) <N>? %
  549.         ^^QMR            !     ask for /C value        !
  550.     '                !    endif            !
  551. '                    ! endif                !
  552. :QQ"E                    ! if Q.str empty        !
  553.     @^UQ%N%                !   Q.str = "N"            !
  554. '                    ! endif                !
  555. 0QQUQ                    ! Q.num = ASCII 1st Q.str char    !
  556. QQ"V                    ! if Q.num lowercase        !
  557.     QQ-32UQ                !   force it to uppercase    !
  558. '                    ! endif                !
  559. QQ-^^N"E                ! if /C == "N"            !
  560.     :@^U9%A%            !   append "A" to 9.str mask    !
  561. |                    ! else                !
  562.     :@^U9%C%            !   append "C" to 9.str mask    !
  563.     QQ-^^Y"E            !   if /C == "Y"        !
  564.         32@^UC%%        !     C.str = <SP>        !
  565.         9:@^UC%%        !     append TAB to C.str    !
  566.     |                !   else (it's a set?)        !
  567.         GQ            !     put /C set in edit buf    !
  568.         ^YXC            !     load it into Q-reg C    !
  569.         ^YK            !     clean up edit buffer    !
  570.     '                !   endif            !
  571. '                    ! endif                !
  572.  
  573. ! --------------------------------------------------------------------- !
  574. ! append entries for all other TECO commands to the mask in Q-reg 9.    !
  575. ! --------------------------------------------------------------------- !
  576.  
  577. !    %"#$%&'()*+,-./0123456789:;<=>?%            !
  578. :@^U9%1..1..........................%
  579.  
  580. !    %@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_%            !
  581. :@^U9%@....EF1.$...1$$.1.$.1..1..1.1^$%
  582.  
  583. !    %`abcdefghijklmnopqrstuvwxyz{|}<tilde><sp>%    !
  584. :@^U9%.LLLLLLLLLLLLLLLLLLLLLLLLLL....D%
  585.  
  586. ! --------------------------------------------------------------------- !
  587. ! Load Q-register 8 with potential <delim> characters in case ESC can't    !
  588. ! be used.  We initially load 8.str with the preferred delimiters:    !
  589. !                                    !
  590. !    / # * & \ ? ( ) $ <exclamation pt> @                !
  591. !                                    !
  592. ! in case these can't be used either, we'll also append every ASCII    !
  593. ! character to 8.str in the hope that something can be used.        !
  594. ! --------------------------------------------------------------------- !
  595.  
  596. @^U8%/#*&\?()$!@%            ! pre-load 8.str        !
  597. 1U8                    ! put 1 in 8.num        !
  598. 126<                    ! this loop appends ASCII chars    !
  599.     Q8:@^U8%% %8^[            ! CTRL-A to TILDE to 8.str    !
  600.    >
  601.  
  602. ! --------------------------------------------------------------------- !
  603. ! Check for /W "Watch progress" switch                    !
  604. ! --------------------------------------------------------------------- !
  605.  
  606. @^UW%%                    ! clear W.str            !
  607. ET&512"E                ! if not scope, ignore /W    !
  608.     J                !   jump to beginning of buf    !
  609.     :@FS%/W%%"S            !   if "/W" found, delete it    !
  610.         ::@FS%:%%"S        !     if ":" found        !
  611.             D        !       delete arg        !
  612.         '            !     endif            !
  613.     '                !   endif            !
  614. |                    ! else (it's a scope)        !
  615.     J                !   jump to beginning of buf    !
  616.     :@FS%/W%%"S            !   if "/W" found        !
  617.         ::@FS%:%%"S        !     if ":arg" found        !
  618.             0A@^UQ%%    !       Q.str = arg        !
  619.             D        !       delete arg        !
  620.         |            !     else            !
  621.             @^UQ%Y%        !       Q.str = "Y"        !
  622.         '            !     endif            !
  623.     |                !   else            !
  624.         QB"T            !     if any other switches    !
  625.             @^UQ%%        !       Q.str = ""        !
  626.         |            !     else            !
  627.             @I%Watch progress (Y/N) <N>? %
  628.             ^^QMR        !       ask for /W value    !
  629.         '            !     endif            !
  630.     '                !   endif            !
  631.     0QQ"A                !   if /W val is alphabetic    !
  632.         0QQ&95-^^Y"E        !     if it's 'y' or 'Y'    !
  633.             0:W-2"E        !       if VT100 in VT52 mode    !
  634.                 4,0:W^[    !         set VT100 in ANSI    !
  635.             '        !       endif            !
  636.             @^UW/-1W/    !       Q.str = "-1W" (refresh)    !
  637.         '            !     endif            !
  638.     '                !   endif            !
  639. '                    ! endif                !
  640.  
  641. ! --------------------------------------------------------------------- !
  642. ! Check for /A "Automatic mode".  If /A:Y, then if @^U%text% is found,    !
  643. ! "text" is assumed to something which should *not* be sub-squished;    !
  644. ! any other character used as a special <delim> *will* be sub-squished.    !
  645. ! If /A:N, then go into "manual mode" where each time SQU runs into    !
  646. ! ^Utext, it will ask if you want to sub-squish it.  If /A:<char> is    !
  647. ! a command line switch then use <char> as the "non-squishable" <delim>    !
  648. ! char.  If you're asked for the /A value, then you can enter a set of    !
  649. ! "non-squishable" <delim> chars.                    !
  650. ! --------------------------------------------------------------------- !
  651.  
  652. @^UK%%                    ! clear K.str            !
  653. J                    ! jump to beginning of buffer    !
  654. :@FS%/A%%"S                ! if "/A" found            !
  655.     ::@FS%:%%"S            !   if ":arg" found        !
  656.         0A@^UQ%%        !     Q.str = arg        !
  657.         D            !     delete arg        !
  658.     |                !   else            !
  659.         @^UQ%Y%            !     Q.str = "Y"        !
  660.     '                !   endif            !
  661. |                    ! else                !
  662.     QB"T                !   if any other switches    !
  663.         @^UQ%Y%            !     Q.str = "Y"        !
  664.     |                !   else            !
  665.         @I/Automatic mode (Y for %, N, or set) <N>? /
  666.         ^^QMR            !     ask for /A value        !
  667.     '                !   endif            !
  668. '                    ! endif                !
  669. :QQ"N                    ! if any /A val            !
  670.     0QQUQ                !   convert /A val to ASCII     !
  671.     QQ"V                !   if /A val lowercase        !
  672.         QQ-32UQ            !     force to uppercase    !
  673.     '                !   endif            !
  674.     QQ-^^N"N            !   if /A not "N"        !
  675.         QQ-^^Y"E        !     if /A == "Y"        !
  676.             ^^%@^UK%%    !       K.str = "%"        !
  677.         |            !     else (it's a set?)    !
  678.             GQ        !       put /A set in edit buf    !
  679.             ^YXK        !     load it into K.str    !
  680.             ^YK        !       clean up edit buffer    !
  681.         '            !     endif            !
  682.     '                !   endif            !
  683. '                    ! endif                !
  684.  
  685. ! --------------------------------------------------------------------- !
  686. ! Check for /E "Allow adjacent ESCapes" switch.  Sometimes squishing    !
  687. ! will put two escapes together where there weren't two escapes before.    !
  688. ! For example, @FS/abc// will be squished to @FSabc$$, the two adjacent    !
  689. ! escapes could be a problem this is in a macro which is EI'd.  The    !
  690. ! format of the /E switch is: /E, /E:N, or /E:Y.  /E is the same as    !
  691. ! /E:Y.  /E:N will direct SQU to never generate adjacent escapes where    !
  692. ! there were none before.                        !
  693. ! --------------------------------------------------------------------- !
  694.  
  695. 0UH                    ! H.num = 0 (FALSE)        !
  696. J                    ! jump to beginning of buffer    !
  697. :@FS%/E%%"S                ! if "/E" found            !
  698.     ::@FS%:%%"S            !   if ":" found        !
  699.         0A@^UQ%%        !     Q.str = arg        !
  700.         D            !     delete arg        !
  701.     |                !   else            !
  702.         @^UQ%Y%            !     Q.str = "Y"        !
  703.     '                !   endif            !
  704. |                    ! else                !
  705.     QB"T                !   if any other switches    !
  706.         @^UQ%%            !     Q.str = ""        !
  707.     |                !   else            !
  708.         @I%Allow adjacent ESCapes (Y/N) <N>? %
  709.         ^^QMR            !     ask for /E value        !
  710.     '                !   endif            !
  711. '                    ! endif                !
  712. 0QQ"A                    ! if /E val is alphabetic    !
  713.     0QQ&95-^^Y"E            !   if it's 'y' or 'Y'        !
  714.         -1UH            !     H.num = -1 (TRUE)        !
  715.     '                !   endif            !
  716. '                    ! endif                !
  717.  
  718. ! --------------------------------------------------------------------- !
  719. ! Load Q-register Z with the squisher macro                !
  720. !                                    !
  721. ! Uses Q-register 1 for @-modified flag while processing and for    !
  722. ! an error return when through.                        !
  723. ! --------------------------------------------------------------------- !
  724.  
  725. @^UZ*                    ! Z.str = squish macro        !
  726. [1                    ! save Q-reg 1            !
  727. 0U1                    ! clear @-modifed flag        !
  728. :QW"N                    ! if /W was TRUE        !
  729.     -1,3:W^[            !   turn on SEEALL mode        !
  730.     0,4:W^[                !   set no "mark" status    !
  731.     0,5:W^[                !   turn hold mode off        !
  732. '                    ! endif                !
  733.  
  734. ! --------------------------------------------------------------------- !
  735. ! main loop start                            !
  736. ! --------------------------------------------------------------------- !
  737.  
  738. <
  739. !..!
  740.  
  741. MW                    ! refresh scope            !
  742.  
  743. !.!
  744.  
  745. ME;                    ! break if E macro returns 0    !
  746.  
  747. 0AU0                    ! 0.num = char in buffer    !
  748. Q0"L                    ! if char is less than zero    !
  749.     @O!OFFEND!            !   end of file err        !
  750. '                    ! endif                !
  751. C                    ! advance one character        !
  752. Q0&128"N                ! if char's hi bit is set    !
  753.     Q0&127U0            !   zero hi bit            !
  754.     -D                !   delete hi bit char        !
  755.     Q0@I%%                !   insert zero hi bit char    !
  756. '                    ! endif                !
  757.  
  758. ! --------------------------------------------------------------------- !
  759. ! Use the ASCII value of the current char in 0.num as an index into the    !
  760. ! labels in 9.str, and goto that label.                    !
  761. ! --------------------------------------------------------------------- !
  762.  
  763. !DISP!                    ! dispatch            !
  764. Q0Q9@^U0%%                ! 0.str = Q0th char of 9.str    !
  765. @O!^EQ0!                ! and jump to it        !
  766.  
  767. ! --------------------------------------------------------------------- !
  768. ! handle a lowercase character.  convert it to uppercase and process    !
  769. ! it again.                                !
  770. ! --------------------------------------------------------------------- !
  771.  
  772. !L!
  773.  
  774. Q0-32U0                    ! convert to uppercase        ! 
  775. -D                    ! delete lowercase char        !
  776. Q0@I%%                    ! insert uppercase char        !
  777. @O!DISP!                ! try label for uppercase char    !
  778.  
  779. ! --------------------------------------------------------------------- !
  780. ! handle '^'.  the next character is really CTRL-char.  we'll delete    !
  781. ! the "^char" construct, insert the "real" control char, and go back    !
  782. ! and process it again.  we'll watch out for inserting ^[ (<ESC>), we    !
  783. ! have to be careful about creating adjacent <ESC>'s.            !
  784. ! --------------------------------------------------------------------- !
  785.  
  786. !^!
  787.  
  788. 0A&31U0                    ! 0.num = ^char            !
  789. C                    ! skip past char        !
  790. -2D                    ! delete both ^ and char    !
  791. QH"F                    ! if no adjacent ESC's         !
  792.     Q0-27"E                !   if ^char is ESC        !
  793.         0A-27"E            !     if next char is ESC    !
  794.             @I%^[%        !       insert a single ESC    !
  795.             C        !       skip past next ESC    !
  796.             @O!..!        !       jump to main loop    !
  797.         '            !     endif            !
  798.         ! ----------------------------------------------------- !
  799.         ! at this point we are trying to insert an ESC; but we    !
  800.         ! don't know if by doing so we will inadvertently form    !
  801.         ! two adjacent escapes.  the following code searches    !
  802.         ! backwards for the last important character (skipping    !
  803.         ! CF/LF's) to see if that last important character was    !
  804.         ! also an ESC.  if it was, we'll insert a <SP> to keep    !
  805.         ! the two ESC's lexically apart.            !
  806.         ! ----------------------------------------------------- !
  807.         .US            !     S.num = cur buf ptr    !
  808.         0UT            !     T.num = 0            !
  809.         <            ! ----loop begin--------------- !
  810.             -.;        !       break if .==0        !
  811.             R        !       back up one char    !
  812.             0AUT        !       T.num = previous char    !
  813.             QT&128"E    !       if hi bit of char zero    !
  814.                 QT-10"N        ! if char is not <LF>    !
  815.                     0;    !   break out of loop    !
  816.                 |        ! else (it is <LF>)    !
  817.                     -.;    !   break if .==0    !
  818.                     -1A-128-13"N ! if not <CR><LF>    !
  819.                         0;  ! break out of loop !
  820.                     '    !   endif        !
  821.                 '        ! endif            !
  822.             '        !       endif            !
  823.         >            ! ----loop end----------------- !
  824.         QSJ            !       jump to where we startd !
  825.         QT-27"E            !       if last char == ESC    !
  826.             @I% %        !         insert <SP>        !
  827.         '            !       endif            !
  828.     '                !     endif            !
  829. '                    !   endif            !
  830. Q0@I%%                    ! insert ^char            !
  831. @O!DISP!                ! try again            !
  832.  
  833. ! --------------------------------------------------------------------- !
  834. ! handle 'B'.  we've run into the <LF> portion of CR/LF with the /B    !
  835. ! switch (delete blank lines) set.  if there are only two chars on the    !
  836. ! current line, assume they are CR/LF and delete them.            !
  837. ! --------------------------------------------------------------------- !
  838.  
  839. !B!
  840.  
  841. -1^Q+2"E                ! if only 2 chars on this line    !
  842.     -2D                !   delete <CR><LF>        !
  843. '                    ! endif                !
  844. @O!..!                    ! jump to main loop        !
  845.  
  846. ! --------------------------------------------------------------------- !
  847. ! handle 'O'.  we've run into <LF>, <CR>, or <LF> with the /L switch    !
  848. ! set.                                     !
  849. ! --------------------------------------------------------------------- !
  850.  
  851. !O!
  852.  
  853. -D                    ! delete last char        !
  854. ."N                    ! if not at beginning of buffer    !
  855.     -1A&128"N            !   if last char hi bit set    !
  856.         -D            !     delete it            !
  857.     '                !   endif            !
  858.     .-1"G                !   if 2 chars past buf begin    !
  859.         -1A-10"E        !     if hi bi of last char set    !
  860.             -2A-128-13"E    !       if 2nd last char = <CR>    !
  861.                 Q0-13"E    !         if curr char is <CR>  !
  862.                     -2D !       delete <CR><CR>    !
  863.                 |    !         else            !
  864.                     @O!..! !    jump to main loop    !
  865.                 '    !         endif            !
  866.             '        !       endif            !
  867.         '            !     endif            !
  868.     '                !   endif            !
  869.     Q0#128@I%%            !   insert char w/hi bit    !
  870.     Q0-13"E                !   if char is <CR>        !
  871.         .-Z"E            !     if at end of buffer    !
  872.             10@I%%        !       insert <LF>        !
  873.             R        !       back up one char    !
  874.         '            !     endif            !
  875.         0A&127-10"E        !     if curr char is <LF>    !
  876.             D        !       delete it        !
  877.         '            !     endif            !
  878.         10@I%%            !   insert <LF>            !
  879.     '                !   endif            !
  880. '                    ! endif                !
  881. @O!..!                    ! jump to main loop        !
  882.  
  883. ! --------------------------------------------------------------------- !
  884. ! handle 'U'.  we've run into ^Uq.  usually, the string ^Uq is loading    !
  885. ! into Q-register q is *not* squished.  the problem with ^Uq is that it    !
  886. ! is sometimes used to load a macro into a Q-register.  This macro code    !
  887. ! should be squished too.  What we do is if the ^U is @-modified, and    !
  888. ! the <delim> is *not* in the "non-squishible ^U command" character set    !
  889. ! in Q-register K, we assume it is a macro and should be sub-squished.    !
  890. ! Otherwise, the ^U argument is assumed to be a simple string and is    !
  891. ! not sub-squished.                            !
  892. ! --------------------------------------------------------------------- !
  893.  
  894. !U!
  895.  
  896. 27@^U1%%                ! 1.str = ESC (default delim)    !
  897. .UC                    ! C.num = current buf ptr    !
  898. 0AU0                    ! 0.num = ^U Q-reg name        !
  899. C                    ! advance past Q-reg name    !
  900. Q0-^^."E                ! if it's .q (local Q-reg name)    !
  901.     0AU0                !   0.num = "real" Q-reg name    !
  902.     C                !   advance past "."        !
  903. '                    ! endif                !
  904. Q0"V                    ! if Q-reg name is lowercase    !
  905.     Q0-32U0                !   convert it to uppercase    !
  906.     -D                !   delete lowercase char    !
  907.     Q0@I%%                !   insert uppercase char    !
  908. '                    ! endif                !
  909. Q1"T                    ! if @-modified            !
  910.     0A-(1A)"E            !   if @^Uq<delim>text<delim>    !
  911.         @O!$$!            !     goto $$            !
  912.     '                !   endif            !
  913. |                    ! else                !
  914.     0A-27"E                !   if ^Uq<ESC>            !
  915.         @O!$$!            !     goto $$            !
  916.     '                !   endif            !
  917. '                    ! endif                !
  918. .US                    ! S.num = current buf ptr    !
  919. Q1"T                    ! if @-modifed            !
  920.     0A@^U1%%            !   1.str = <delim>        !
  921.     D                !   delete <delim>        !
  922. '                    ! endif                !
  923. :QW"N                    ! if /W was TRUE        !
  924.     :@S%^EQ1%"U            !   if search for <delim> fails !
  925.         @O!STRINGFAIL!        !     unterminated string    !
  926.     '                !   endif            !
  927.     .,4:W^[                !   set mark status        !
  928.     QSJ                !   jump back to where we were    !
  929.     MW                !   refresh scope        !
  930. '                    ! endif                !
  931.  
  932. ! --------------------------------------------------------------------- !
  933. ! if there are no "non-squishable ^U command" characters, you used the    !
  934. ! /A:N switch.  If this is the case, we'll have to drop into "manual"    !
  935. ! mode:  everytime we run into a ^U we'll ask if you want to squish it    !
  936. ! or not, Y or N.                            !
  937. ! --------------------------------------------------------------------- !
  938.  
  939. :QK"E                    ! if no non-squishable ^U delim    !
  940.     :QW"E                !   if /W was FALSE        !
  941.         0T            !     display line up to now    !
  942.         10^T            !     display <LF>        !
  943.         T            !     display rest of line    !
  944.     '                !   endif            !
  945.     7^T                !   display <BEL>        !
  946.     ETUQ                !   save ET flags in Q.num    !
  947.     ET#8#4-4ET            !   turn on read w/o echo    !
  948.     ^TU0                !   read char into 0.num    !
  949.     QQET                !   restore ET flags        !
  950. |                    ! else (non-squishable delims)    !
  951.     G1                !   put <delim> in buf        !
  952.     R                !   back up one char        !
  953.     ::@S%^EGK%"S            !   if <delim> is non-squish    !
  954.         -D            !     delete <delim>        !
  955.             ^^NU0        !     0.num = N            !
  956.     |                !   else            !
  957.         D            !     delete <delim>        !
  958.         ^^YU0            !     0.num = Y            !
  959.     '                !   endif            !
  960. '                    ! endif                !
  961. :QW"N                    ! if /W was TRUE        !
  962.     0,4:W^[                !   clear "mark" status        !
  963.     32768W                !   set huge # of display lines    !
  964. '                    ! endif                !
  965.  
  966. ! --------------------------------------------------------------------- !
  967. ! at this point, 0.num will be "Y" if we are to sub-squish the ^U text    !
  968. ! --------------------------------------------------------------------- !
  969.  
  970. Q0-^^Y"E                ! if 0.num is Y            !
  971.     ! ------------------------------------------------------------- !
  972.     ! Q-register E originally holds ".-Z" (-number of chars until    !
  973.     ! end of the buffer, when zero we're at end of buf).  The E    !
  974.     ! macro is executed at the top of the squish loop so we break    !
  975.     ! out of the squish loop when we reach the end of the buf. When    !
  976.     ! we recursively sub-squish a ^U string, we want the squish    !
  977.     ! loop to break out when it reaches the end of the ^U string.    !
  978.     ! Therefore, we'll now load Q-register E with a macro to do so.    !
  979.     !                                !
  980.     !    -1UE            E.num == -1 (continue flag)    !
  981.     !    0A-^^<delim>"E        if we've run into <delim>    !
  982.     !        0UE          E.num == 0 (break flag)    !
  983.     !    '            endif                !
  984.     !    QE            push -1 or 0 on stack        !
  985.     ! ------------------------------------------------------------- !
  986.     [E [C [S            !   save Q-reg's E, C, & S    !
  987.     @^UE%-1UE0A-^^%            !   load Q-reg E w/macro start    !
  988.     0Q1:@^UE%%            !   append <delim> to Q-reg E    !
  989.     :@^UE%"E0UE'QE%            !   append macro end to Q-reg E    !
  990.     MZ                !   squish recursively        !
  991.     ]S ]C ]E            !   restore Q-reg's C, S & E    !
  992.     "N                !   if recursive MZ failed    !
  993.         @O!PRIORFAIL!        !     announce it        !
  994.     '                !   endif            !
  995.     C                !   advance past end ^U delim    !
  996.     @O!$$$$!            !   goto $$$$            !
  997. '                    ! endif                !
  998. @O!$$$!                    ! goto $$$            !
  999.  
  1000. ! --------------------------------------------------------------------- !
  1001. ! handle 'T'.  we've run into a TAB character, start an insert.        !
  1002. ! --------------------------------------------------------------------- !
  1003.  
  1004. !T!
  1005.  
  1006. 0U1                    ! clear @-modified flag        !
  1007.  
  1008. ! --------------------------------------------------------------------- !
  1009. ! handle '$'.  we've run into I, N, O, or S: commands which take a    !
  1010. ! single string argument (ie: commands which contain one <delim>).    !
  1011. ! --------------------------------------------------------------------- !
  1012.  
  1013. !$!
  1014.  
  1015. 27@^U1%%                ! 1.str = ESC (default delim)    !
  1016. .UC                    ! C.num = current buf ptr    !
  1017.  
  1018. ! --------------------------------------------------------------------- !
  1019. ! $$, entry point for commands which take two string arguments (ie:    !
  1020. ! commands which contain two <delim>'s).                !
  1021. ! --------------------------------------------------------------------- !
  1022.  
  1023. !$$!
  1024.  
  1025. .US                    ! S.num = start of text        !
  1026. Q1"T                    ! if @-modified            !
  1027.     0A@^U1%%            !   1.str = <delim>        !
  1028.     D                !   delete <delim>        !
  1029. '                    ! endif                !
  1030.  
  1031. ! --------------------------------------------------------------------- !
  1032. ! $$$, entry point for the ^U routine when we are not sub-squishing the !
  1033. ! ^U argument, but we've already handled being @-modified.        !
  1034. ! --------------------------------------------------------------------- !
  1035.  
  1036. !$$$!
  1037.  
  1038. :@S%^EQ1%"U                ! if search for <delim> fails    !
  1039.     @O!STRINGFAIL!            !   unterminated string        !
  1040. '                    ! endif                !
  1041.  
  1042. ! --------------------------------------------------------------------- !
  1043. ! $$$$, entry point for the ^U routine after we've sub-squished a ^U    !
  1044. ! macro.                                !
  1045. ! --------------------------------------------------------------------- !
  1046.  
  1047. !$$$$!
  1048.  
  1049. -D                    ! delete trailing <delim>    !
  1050. .UT                    ! T.num = end of text        !
  1051. 27U0                    ! 0.num = ESC (default <delim>    !
  1052.  
  1053. ! --------------------------------------------------------------------- !
  1054. ! At this point, we have to output a delimited string.            !
  1055. !                                    !
  1056. !    0.num = <delim>                            !
  1057. !    C.num = start of command                    !
  1058. !    S.num = start of text                        !
  1059. !    T.num = end of text                        !
  1060. !                                    !
  1061. ! --------------------------------------------------------------------- !
  1062.  
  1063. !AA!
  1064.  
  1065. Q0@^U0%%                ! 0.str = <delim> char        !
  1066. QT-QS"G                    ! if string is not-empty    !
  1067.     QSJ                !   jump to start of string    !
  1068.     .,.+QT-QS:@FB%^EQ0%"S        !   if <delim> is in string    !
  1069.         ! ----------------------------------------------------- !
  1070.         ! find a <delim> we can use, one which is *not* already !
  1071.         ! in the string.                    !
  1072.         ! ----------------------------------------------------- !
  1073.         G8            !     put 8.str into buf    !
  1074.         ^Y:X1            !     put 8.str into 1.str    !
  1075.         ^YK            !     kill 8.str from buf    !
  1076.         0U0            !     clear 0.num        !
  1077.         <            ! ----loop begin---------------    !
  1078.             Q0Q1@^U0%%    !       0.str = Q0th char of Q1    !
  1079.             QSJ        !       jump to start of text    !
  1080.             .,.+QT-QS@FB%^EQ0%; !   break if search fails    !
  1081.             %0-:Q8"E    !       if next char last char    !
  1082.                 @O!NOQUOTE!    ! can't find " char    !
  1083.             '        !       endif            !
  1084.         >            ! ----loop end----------------- !
  1085.         Q0Q1U0            !     0.num = <delim> to use    !
  1086.         QSJ            !     jump to start of string    !
  1087.         Q0@I%%            !     insert <delim>        !
  1088.         QC-1J            !     jump before command    !
  1089.         @I%@%            !     insert @            !
  1090.         2%T^[            !     T.num (end of text) += 2    !
  1091.         ! ----------------------------------------------------- !
  1092.     '                !   endif            !
  1093. '                    ! endif                !
  1094. QTJ                    ! jump to end of string        !
  1095. Q0@I%%                    ! insert <delim>        !
  1096. 0U1                    ! clear @-modified flag        !
  1097. @O!..!                    ! jump to main loop        !
  1098.  
  1099. ! --------------------------------------------------------------------- !
  1100. ! handle '1'.  we've run into ", %, G, M, Q, U, X, [, or ].  For ", the    !
  1101. ! next character is a conditional execution command.  For everything    !
  1102. ! else, the next character is a Q-register name.  In either case, if    !
  1103. ! the next char is lowercase, we uppercase it; otherwise, we fall    !
  1104. ! through to the 'V' code below which simply advances past the char.    !
  1105. ! --------------------------------------------------------------------- !
  1106.  
  1107. !1!
  1108.  
  1109. 0A-^^."E                ! if it's .q (local Q-reg name)    !
  1110.     C                !   advance past "."        !
  1111. '                    ! endif                !
  1112. 0A"V                    ! if lowercase            !
  1113.     0A-32U0                !   convert to uppercase    !
  1114.     D                !   delete lowercase char    !
  1115.     Q0@I%%                !   insert uppercase char    !
  1116.     @O!.!                !   goto .            !
  1117. '                    ! endif                !
  1118. ! ... fall through ...!
  1119.  
  1120. ! --------------------------------------------------------------------- !
  1121. ! handle 'V'.  we've run into <CTRL>-^, simply skip it            !
  1122. ! --------------------------------------------------------------------- !
  1123.  
  1124. !V!
  1125.  
  1126. C                    ! simply advance past it    !
  1127. @O!.!                    ! goto .            !
  1128.  
  1129. ! --------------------------------------------------------------------- !
  1130. ! handle '@'.  the following command is @ modified, set a flag in 1.num    !
  1131. ! so we know to look for the alternate delimiter characters.        !
  1132. !                                    !
  1133. ! even though <delim> characters will be specified along with the '@'    !
  1134. ! command, we'll try to use ESC whenever possible and convert the @    !
  1135. ! modified command back into a "normally" delimited command.        !
  1136. ! --------------------------------------------------------------------- !
  1137.  
  1138. !@!
  1139.  
  1140. -1U1                    ! set @-modified flag        !
  1141. ! ...fall through ... !
  1142.  
  1143. ! --------------------------------------------------------------------- !
  1144. ! handle 'D'.  delete the character from the output file        !
  1145. ! --------------------------------------------------------------------- !
  1146.  
  1147. !D!
  1148.  
  1149. -D                    ! delete last character        !
  1150. @O!.!
  1151.  
  1152. ! --------------------------------------------------------------------- !
  1153. ! handle 'F'.  we've run into a F', F<. F>, F|, FB, FC, FD, FK, FN, FR,    !
  1154. ! FS, or F_ command.                            !
  1155. ! --------------------------------------------------------------------- !
  1156.  
  1157. !F!
  1158.  
  1159. 27@^U1%%                ! 1.str = ESC (default delim)    !
  1160. .UC                    ! C.num = current buf ptr    !
  1161. 0AU0                    ! 0.num = 2nd command char    !
  1162. C                    ! advance past 2nd cmd char    !
  1163. Q0"V                    ! if 2nd cmd char is lowercase    !
  1164.     Q0-32U0                !   convert it to uppercase    !
  1165.     -D                !   delete lowercase char    !
  1166.     Q0@I%%                !   insert uppercase char    !
  1167. '                    ! endif                !
  1168.  
  1169. ! --------------------------------------------------------------------- !
  1170. ! the FB and FR commands take a single string argument, goto $$        !
  1171. ! the FC, FS, FN, and F_ commands take two string arguments, goto F$$    !
  1172. !                                    !
  1173. ! ???What about FD and FK taking 1 string argument            !
  1174. ! --------------------------------------------------------------------- !
  1175.  
  1176. Q0-^^B"E                ! if it's FB            !
  1177.     @O!$$!                !   goto $$            !
  1178. '                    ! endif                !
  1179. Q0-^^C"E                ! if it's FC            !
  1180.     @O!F$$!                !   goto F$$            !
  1181. '                    ! endif                !
  1182. Q0-^^R"E                ! if it's FR            !
  1183.     @O!$$!                !   goto $$            !
  1184. '                    ! endif                !
  1185. Q0-^^S"E                ! if it's FS            !
  1186.     @O!F$$!                !   goto F$$            !
  1187. '                    ! endif                !
  1188. Q0-^^N"E                ! if it's FN            !
  1189.     @O!F$$!                !   goto F$$            !
  1190. '                    ! endif                !
  1191. Q0-^^_"E                ! if it's F_            !
  1192.     @O!F$$!                !   goto F$$            !
  1193. '                    ! endif                !
  1194. @O!.!
  1195.  
  1196. ! --------------------------------------------------------------------- !
  1197. ! handle FC, FS, FN, and F_ commands which take two string arguments,    !
  1198. ! there are three possible formats for these commands:            !
  1199. !                                    !
  1200. !    Fx <delim> <delim>                        !
  1201. !    Fx text <delim> <delim>                        !
  1202. !    Fx text1 <delim> text2 <delim>                    !
  1203. !                                    !
  1204. ! we first have to find the starting and ending points of the text    !
  1205. ! arguments.  we set S.num to be the start of text1, we look for the    !
  1206. ! 1st <delim>, delete it, and set T.num to be the start of text2.  we    !
  1207. ! then look for the 2nd <delim>, delete it, and set U.num to be the    !
  1208. ! end of text2.                                !
  1209. !                                    !
  1210. ! if S.num == T.num & T.num == U.num, then we have: FS$$        !
  1211. ! if S.num <> T.num & T.num == U.num, then we have: FStext$$        !
  1212. ! if S.num <> T.num & T.num <> U.num, then we have: FStext1$text2    !
  1213. ! --------------------------------------------------------------------- !
  1214.  
  1215. !F$$!
  1216.  
  1217. .US                    ! S.num = start of text1    !
  1218. 27@^U1%%                ! 1.str = ESC (default delim)    !
  1219. Q1"T                    ! if @-modified            !
  1220.     0A@^U1%%            !   1.str = <delim>        !
  1221.     D                !   delete <delim>        !
  1222. '                    ! endif                !
  1223. :@S%^EQ1%"U                ! if search for 1st delim fails !
  1224.     @O!STRINGFAIL!            !   unterminated string        !
  1225. '                    ! endif                !
  1226. -D                    ! delete 1st <delim>        !
  1227. .UT                    ! T.num = start of text2    !
  1228. :@S%^EQ1%"U                ! if search for 2nd delim fails    !
  1229.     @O!STRINGFAIL!            !   unterminated string        !
  1230. '                    ! endif                !
  1231. -D                    ! delete 2nd <delim>        !
  1232. .UU                    ! U.num = end of text2        !
  1233. QH"T                    ! if allow adjacent escapes    !
  1234.     27U0                !   0.num = ESC            !
  1235.     Q0@^U0%%            !   0.str = ESC            !
  1236.     QU-QS"G                !   if we have text1 & text2    !
  1237.         QSJ            !     jump to start of text1    !
  1238.         .,.+QU-QS:@FB%^EQ0%"U    !     if search for ESC fails    !
  1239.             @O!F0!        !       use ESC as <delim>    !
  1240.         '            !     endif            !
  1241.     |                !   else (no text arguments)    !
  1242.         @O!F0!            !     use ESC as DELIM        !
  1243.     '                !   endif            !
  1244. |                    ! else (don't allow adjacent $)    !
  1245.     QU-QT"G                !   if we have text2        !
  1246.         27U0            !     0.num = ESC        !
  1247.         Q0@^U0%%        !     0.str = ESC        !
  1248.         QSJ            !     jump to start of text1    !
  1249.         .,.+QU-QS:@FB%^EQ0%"U    !     if search for ESC fails    !
  1250.             @O!F0!        !       done w/F        !
  1251.         '            !     endif            !
  1252.     '                !   endif            !
  1253. '                    ! endif                !
  1254.  
  1255. ! --------------------------------------------------------------------- !
  1256. ! if we reach this point, there is a danger of putting adjacent ESC's    !
  1257. ! in the output.  we will try to find a character that's not in the    !
  1258. ! string we're delimiting and use that as a <delim> character instead    !
  1259. ! of ESC.  basically, we search "text1text2" looking for each character    !
  1260. ! in G8, trying to find a delimiter char that's not already in the    !
  1261. ! string.                                !
  1262. ! --------------------------------------------------------------------- !
  1263.  
  1264. G8                    ! put 8.str into buf        !
  1265. ^Y:X1                    ! put 8.str into 1.str        !
  1266. ^YK                    ! kill 8.str from buf        !
  1267. 0U0                    ! 0.num = 0            !
  1268. <                    ! loop begin------------------- !
  1269.     Q0Q1@^U0%%            !   0.str = 0.num'th char of Q1    !
  1270.     QSJ                !   jump to start of text1    !
  1271.     .,.+QU-QS@FB%^EQ0%;        !   break if 0.str search fails    !
  1272.     %0-:Q8"E            !   inc 0.num, if end of 8.str    !
  1273.         @O!NOQUOTE!        !     can't find " char        !
  1274.     '                !   endif            !
  1275. >                    ! loop end--------------------- !
  1276.  
  1277. ! --------------------------------------------------------------------- !
  1278. ! at this point, we've found our <delim> char, it's index is in 0.num    !
  1279. ! --------------------------------------------------------------------- !
  1280.  
  1281. Q0Q1U0                    ! 0.num = Q0th char of Q1    !
  1282. QSJ                    ! jump to start of text1    !
  1283. Q0@I%%                    ! insert <delim>        !
  1284. QC-1J                    ! jump 1 char before F command    !
  1285. @I%@%                    ! insert @            !
  1286. 2%T^[                    ! T.num (end of text1) += 2    !
  1287. 2%U^[                    ! U.num (end of text2) += 2    !
  1288.  
  1289. !F0!
  1290.  
  1291. QTJ                    ! jump to end of text1        !
  1292. Q0@I%%                    ! insert <delim>        !
  1293. QU-QTC                    ! advance to end of text2    !
  1294. Q0@I%%                    ! insert <delim>        !
  1295. 0U1                    ! clear @-modified flag        !
  1296. @O!..!                    ! jump to main loop        !
  1297.  
  1298. ! --------------------------------------------------------------------- !
  1299. ! handle 'A'.  we've run into ^Atext^A or @^A/text/.  This is also the    !
  1300. ! entry point for the 'C' routine:  if we're not deleting the comment    !
  1301. ! we handle <exclamation-point>comment<exclamation-point> just like     !
  1302. ! ^Atest^A.                                                             !
  1303. ! --------------------------------------------------------------------- !
  1304.  
  1305. !A!
  1306.  
  1307. Q0@^U1%%                ! 1.str = ^A or exclamation pt.    !
  1308. .UC                    ! C.num = start of text        !
  1309. .US                    ! S.num = start of text        !
  1310. Q1"T                    ! if @-modified            !
  1311.     0A@^U1%%            !   1.str = <delim>        !
  1312.     D                !   delete <delim>        !
  1313. '                    ! endif                !
  1314. :@S%^EQ1%"U                ! if search for <delim> fails    !
  1315.     @O!STRINGFAIL!            !   unterminated string        !
  1316. '                    ! endif                !
  1317. -D                    ! delete second <delim>        !
  1318. .UT                    ! T.num = end of text        !
  1319. @O!AA!                    ! goto AA            !
  1320.  
  1321. ! --------------------------------------------------------------------- !
  1322. ! handle 'C'.  we've run into an exclamation point with the /C switch    !
  1323. ! set.  Q-register C contains the special comment delimiter characters. !
  1324. ! --------------------------------------------------------------------- !
  1325.  
  1326. !C!
  1327.  
  1328. ::@S%^EGC%"U                ! if not special comment delim    !
  1329.     @O!A!                !   handle like ^Astring^A    !
  1330. '                    ! endif                !
  1331. R                    ! back up past special <delim>    !
  1332. .UC                    ! C.num = current buf ptr    !
  1333. Q0@^U1%%                ! 1.str = exclamation point    !
  1334. Q1"T                    ! if @-modified            !
  1335.     0A@^U1%%            !   1.str = <delim>        !
  1336.     D                !   delete <delim>        !
  1337. '                    ! endif                !
  1338. :@S%^EQ1%"U                ! if search for <delim> failed    !
  1339.     @O!STRINGFAIL!            !   unterminated string        !
  1340. '                    ! endif                !
  1341. QC-1,.K                    ! kill entire comment        !
  1342. 0U1                    ! clear @-modified flag        !
  1343. @O!..!                    ! jump to main loop        !
  1344.  
  1345. ! --------------------------------------------------------------------- !
  1346. ! handle 'E'.  we've run into an E command.                             !
  1347. ! --------------------------------------------------------------------- !
  1348.  
  1349. !E!
  1350.  
  1351. 27@^U1%%                ! 1.str = ESC (default delim)    !
  1352. .UC                    ! C.num = current buf ptr    !
  1353. 0AU0                    ! 0.num = 2nd command char    !
  1354. C                    ! advance past 2nd cmd char    !
  1355. Q0"V                    ! if 2nd cmd char is lowercase    !
  1356.     Q0-32U0                !   convert to uppercase    !
  1357.     -D                !   delete lowercase char    !
  1358.     Q0@I%%                !   insert uppercase char    !
  1359. '                    ! endif                !
  1360.  
  1361. ! --------------------------------------------------------------------- !
  1362. ! the EB, EG, EI, EN, ER, EW, E_ commands take a string argument, they    !
  1363. ! have to be passed to the $$ routine.                    !
  1364. ! ???What about EL, EQq, EZ, and E%q taking a string argument        !
  1365. ! --------------------------------------------------------------------- !
  1366.  
  1367. Q0-^^B"E                ! if it's EB            !
  1368.     @O!$$!                !   goto $$            !
  1369. '                    ! endif                !
  1370. Q0-^^G"E                ! if it's EG            !
  1371.     @O!$$!                !   goto $$            !
  1372. '                    ! endif                !
  1373. Q0-^^I"E                ! if it's EI            !
  1374.     @O!$$!                !   goto $$            !
  1375. '                    ! endif                !
  1376. Q0-^^N"E                ! if it's EN            !
  1377.     @O!$$!                !   goto $$            !
  1378. '                    ! endif                !
  1379. Q0-^^R"E                ! if it's ER            !
  1380.     @O!$$!                !   goto $$            !
  1381. '                    ! endif                !
  1382. Q0-^^W"E                ! if it's EW            !
  1383.     @O!$$!                !   goto $$            !
  1384. '                    ! endif                !
  1385. Q0-^^_"E                ! if it's E_            !
  1386.     @O!$$!                !   goto $$            !
  1387. '                    ! endif                !
  1388. @O!.!
  1389.  
  1390. ! --------------------------------------------------------------------- !
  1391. ! handle 'Z'.  we've run into a ^Z, replace it with <CARET>-Z        !
  1392. ! --------------------------------------------------------------------- !
  1393.  
  1394. !Z!
  1395.  
  1396. -D                    ! delete <CTRL>-Z        !
  1397. @I%^Z%                    ! insert <CARET>-Z        !
  1398. @O!..!                    ! jump to main loop        !
  1399.  
  1400. >                    ! main loop end----------------    !
  1401.  
  1402. ! --------------------------------------------------------------------- !
  1403. ! At this point, everything should be squished and Q1 will be -1 if    !
  1404. ! an error occurred, or 0 if everything is OK.                !
  1405. ! --------------------------------------------------------------------- !
  1406.  
  1407. Q1"T                    ! if error flag            !
  1408.     @^U1%Trailing, pending @%    !                !
  1409.     @O!ERROR!            !   goto error display        !
  1410. '                    ! endif                !
  1411. 0U1                    ! clear Z-macro return value    !
  1412.  
  1413. ! --------------------------------------------------------------------- !
  1414. ! the only way the following error reporting code is executed is if we    !
  1415. ! jump to a label inside of it.  if we arrive here by any other means    !
  1416. ! then things are OK, skip down to the "endif".                !
  1417. ! --------------------------------------------------------------------- !
  1418.  
  1419. 0"N                    ! skip the following code    !
  1420. !OFFEND!
  1421.     @^U1%End of buffer while sub-squishing%
  1422.     @O!ERROR!
  1423.  
  1424. !NOQUOTE!
  1425.     @^U1%Can't find a quote character%
  1426.     @O!SETPOS!
  1427.  
  1428. !PRIORFAIL!
  1429.     @^U1%Prior recursion level failed%
  1430.     @O!SETPOS!
  1431.  
  1432. !STRINGFAIL!
  1433.     @^U1%Unterminated string%
  1434.  
  1435. ! --------------------------------------------------------------------- !
  1436. ! the following code finishes building an error string in Q-register 1.    !
  1437. ! 1.str already contains the type of error, this code appends the    !
  1438. ! position where the error occurred and the line before and after the    !
  1439. ! error, like so:                            !
  1440. !                                    !
  1441. !    <error message> from squished .=<error position>        !
  1442. !    <line up to error>|                        !
  1443. !               |<line after error>                !
  1444. !                                    !
  1445. ! --------------------------------------------------------------------- !
  1446.  
  1447. !SETPOS!
  1448.     :@^U1% from squished .=%    !   append msg to 1.str        !
  1449.     QC\                !   position in C.num to buf    !
  1450.     ^Y:X1                !   append position in buf    !
  1451.     ^YK                !   delete position from buf    !
  1452.     13:@^U1%%            !   append <CR>            !
  1453.     10:@^U1%%            !   append <LF>            !
  1454.     QCJ                !   jump to where error starts    !
  1455.     0^Q+.,.:X1            !   append line up to error    !
  1456.     ^^|:@^U1%%            !   append |            !
  1457.     10:@^U1%%            !   append <LF>            !
  1458.     ^^|:@^U1%%            !   append |            !
  1459.     .,^Q+.:X1            !   append rest of line        !
  1460.  
  1461. !ERROR!
  1462.     ZJ                !  jump to buf end        !
  1463.     MW                !  refresh scope        !
  1464.     0,0XW                !  clear W.str (/W switch)    !
  1465.     7^T                !  sound bell            !
  1466.     ^^?^T                !  display "?"            !
  1467.     :G1                !  display 1.str        !
  1468.     7^T                !  sound bell            !
  1469.     13^T                !  display <CR>            !
  1470.     10^T                !  display <LF>            !
  1471.     -1U1                !  set Z-macro return to -1    !
  1472. '                    ! endif                !
  1473. Q1                    ! push Z-macro return val    !
  1474. ]1                    ! restore Q-reg 1        !
  1475. *                    ! end of ^UZ            !
  1476.  
  1477. ! --------------------------------------------------------------------- !
  1478. ! Done loading squisher macro into Q-register Z                !
  1479. ! --------------------------------------------------------------------- !
  1480.  
  1481. ! --------------------------------------------------------------------- !
  1482. ! Load squish driver macro into Q-register A                !
  1483. ! --------------------------------------------------------------------- !
  1484.  
  1485. @^UA*                    ! A.str = squish driver macro    !
  1486. -1^X                    ! search flag = exact matches    !
  1487. @^UE%.-Z%                ! E.str = -# chars to buf end    !
  1488. QO"N                    ! if max line length not 0    !
  1489.     ZJ                !   jump buf end        !
  1490.     @I% %                !   insert <SP>, insure we halt    !
  1491. '                    ! endif                !
  1492. J                    ! jump to beginning of buffer    !
  1493. MZ"E                    ! if squish macro returns OK    !
  1494.     ! ------------------------------------------------------------- !
  1495.     ! at this point, everything is squished; but, if the /L switch    !
  1496.     ! was set, we've deleted all lexical CR/LF's and have to go    !
  1497.     ! back and insert CR/LF wherever needed so the line is no    !
  1498.     ! longer than the width specified with /L:nn.            !
  1499.     ! ------------------------------------------------------------- !
  1500.     QO"N                !   if max line length not 0    !
  1501.         :QW"N            !     if /W was TRUE        !
  1502.             -1,3:W^[    !       turn on SEEALL mode    !
  1503.             0,4:W^[        !       clear "mark" status    !
  1504.             0,5:W^[        !       turn off hold mode    !
  1505.         '            !     endif            !
  1506.         J            !     jump to beginning of buf    !
  1507.         <            ! ----loop begin--------------- !
  1508.             MW        !       refresh scope        !
  1509.             ! --------------------------------------------- !
  1510.             ! the following loop advances through the edit    !
  1511.             ! buffer, looking for a character with the high    !
  1512.             ! bit set.                    !
  1513.             ! --------------------------------------------- !
  1514.             <        ! ------loop begin------------- !
  1515.                 0A&128"N    ! if high bit is set    !
  1516.                     0;    !   break out of loop    !
  1517.                 '        ! endif            !
  1518.                 C    !         advance 1 char    !
  1519.             >        ! ------loop end--------------- !
  1520.             0A&127-13"E    !       if char is <CR>        !
  1521.                 D    !         delete it        !
  1522.             '        !       endif            !
  1523.             D        !    delete <LF>        !
  1524.             .-Z;        !       break if at end of buf    !
  1525.             .U0        !       0.num = current buf ptr    !
  1526.             ! --------------------------------------------- !
  1527.             ! --------------------------------------------- !
  1528.             <        ! ------loop begin------------- !
  1529.                 0A&128"N    ! if hi bit clear    !
  1530.                     0;    !   break out of loop    !
  1531.                 '        ! endif            !
  1532.                 C    !         advance 1 char    !
  1533.             >        ! ------loop end--------------- !
  1534.             ! --------------------------------------------- !
  1535.             ! --------------------------------------------- !
  1536.             <        ! ------loop begin------------- !
  1537.                 .U1    !         1.num = cur buf ptr    !
  1538.                 0L    !         go to begin of line    !
  1539.                 .-Q0-1"L    ! if            !
  1540.                     0;    !   break out of loop    !
  1541.                 '        ! endif            !
  1542.                 R    !         back up one char    !
  1543.             >        ! ------loop end--------------- !
  1544.             Q1J
  1545.             -(0^Q)-QO"G    !       if            !
  1546.                 Q0J    !                !
  1547.                 -1A-27"E    ! if last char was ESC    !
  1548.                     @I% %    !   insert <SP>        !
  1549.                 '        ! endif            !
  1550.                 @I%
  1551. %                    !       insert <CR><LF>        !
  1552.             '        !       endif            !
  1553.         >            ! ----loop end----------------- !
  1554.         ! ----------------------------------------------------- !
  1555.         ! the following loop deletes trailing CR's, LF's, and    !
  1556.         ! <SP>'s from the end of the buffer            !
  1557.         ! ----------------------------------------------------- !
  1558.         <            ! ----loop begin--------------- !
  1559.             ZJ        !       jump to buf end        !
  1560.             -Z;        !       break if buf empty    !
  1561.             -1A-10"N    !       is it LF?        !
  1562.                 -1A-13"N    ! is it CR?        !
  1563.                     -1A-32"N    !   is it <SP>?    !
  1564.                         0;    !     break    !
  1565.                     '        !   endif    !
  1566.                 '        ! endif            !
  1567.             '        !       endif            !
  1568.             -D        !       delete it        !
  1569.         >            ! ----loop end----------------- !
  1570.         MW            !     refresh scope        !
  1571.     '                !   endif            !
  1572.     ! ------------------------------------------------------------- !
  1573.     ! make sure the edit buffer ends in a CR/LF.            !
  1574.     ! ------------------------------------------------------------- !
  1575.     QH"F                !   if no adjacent escapes    !
  1576.         ZJ            !     jump to buf end        !
  1577.         ."E            !     if at beginning of buf    !
  1578.             10@I%%        !       insert <LF>        !
  1579.         '            !     endif            !
  1580.         -1A-10"N        !     if prev char is not <LF>    !
  1581.             10@I%%        !       insert <LF>        !
  1582.         '            !     endif            !
  1583.         R            !     back up one char        !
  1584.         ."E            !     if at beginning of buf    !
  1585.             13@I%%        !       insert <CR>        !
  1586.         '            !     endif            !
  1587.         -1A-13"N        !     if prev char is not <CR>    !
  1588.             13@I%%        !       insert <CR>        !
  1589.         '            !     endif            !
  1590.     '                !   endif            !
  1591.     ZJ                !   jump to buf end        !
  1592.     ! ------------------------------------------------------------- !
  1593.     ! clean up the scope                        !
  1594.     ! ------------------------------------------------------------- !
  1595.     :QW"N                !   if /W was TRUE        !
  1596.         0:W-4"E            !     if VT100 in ANSI mode    !
  1597.             2,0:W^[        !       set VT100 in VT52 mode    !
  1598.         '            !     endif            !
  1599.         -1,3:W^[        !     turn on SEEALL mode    !
  1600.         0,4:W^[            !     clear "mark" status    !
  1601.         MW            !     refresh scope        !
  1602.     '                !   endif            !
  1603. |                    ! else (Z macro returned err)    !
  1604.     @^A/?Squish run failed; aborting any output
  1605. /                    !   warn user            !
  1606.     0,0XF                !   clear F.str            !
  1607. '                    ! endif                !
  1608. 0^X                    ! reset search mode flag    !
  1609. *                    ! end of ^UA            !
  1610.  
  1611. ! --------------------------------------------------------------------- !
  1612. ! Done loading squish driver macro into Q-register A            !
  1613. ! --------------------------------------------------------------------- !
  1614.  
  1615. ! --------------------------------------------------------------------- !
  1616. ! If nothing is in the edit buffer, as them to input the name of the    !
  1617. ! input file and insert it into the buffer.                !
  1618. ! --------------------------------------------------------------------- !
  1619.  
  1620. Z"E                    ! if edit buffer is empty    !
  1621.     @I%File <.TES or .TEC>? %    !   ask for input file        !
  1622.     ^^QMR                !   get response in Q.str    !
  1623.     GQ                !   and put it into the buffer    !
  1624. '                    ! endif                !
  1625. 0,0XR                    ! clear R.str (response macro)    !
  1626. 0,0XQ                    ! clear Q.str (user responses)    !
  1627.                     ! end of ^UF            !
  1628.  
  1629. ! --------------------------------------------------------------------- !
  1630. ! Done loading initialization macro into Q-register F            !
  1631. ! --------------------------------------------------------------------- !
  1632.  
  1633.             ! execute everything up until this point    !
  1634.  
  1635. ! --------------------------------------------------------------------- !
  1636. ! S t a r t   H e r e                            !
  1637. ! --------------------------------------------------------------------- !
  1638.  
  1639. @EI%%            ! close current EI command            !
  1640. MF            ! execute initialization macro in F.str        !
  1641. 0,0XF            ! clear F.str                    !
  1642.  
  1643. Z"E            ! if no command line in buffer            !
  1644.     @^A%Enter your macro then type MA$$
  1645. %            !   ask them to input a macro to squeeze    !
  1646. |            ! else (the buffer isn't empty)            !
  1647.  
  1648.     ! ------------------------------------------------------------- !
  1649.     ! If the edit buffer isn't empty, it must contain the input    !
  1650.     ! filename, and it might contain the output filename like so:    !
  1651.     !                                !
  1652.     !    [OUTFILE[.TEC]=]INFILE[.TES]                !
  1653.     !                                !
  1654.     ! Executing the F macro above has stripped all the switches    !
  1655.     ! from the command line in the edit buffer.            !
  1656.     !                                !
  1657.     ! First, deal with an output filename.  If an output filename    !
  1658.     ! exists on the command line, we might append a .TEC filetype    !
  1659.     ! to it if a filetype wasn't specified.  Then we'll load Q-reg    !
  1660.     ! F with "EWfilename$" to open it for output and remove the    !
  1661.     ! output filename from the buffer.                !
  1662.     ! ------------------------------------------------------------- !
  1663.  
  1664.     J                ! jump to start of buffer    !
  1665.     :@FS%=%%"S            ! if "=" found, have output fn    !
  1666.         @^UF%EW%        !   put "EW" in F.str        !
  1667.         0,.:XF            !   append fn to F.str        !
  1668.         .UF            !   put cp in F.num        !
  1669.         -:@S%.%"U        !   if no ".", no file type    !
  1670.             :@^UF%.TEC%    !     append ".TEC"        !
  1671.         '            !   endif            !
  1672.         QFJ            !   jump to end of filename    !
  1673.         27:@^UF%%        !   append ESC to F.str        !
  1674.         QB"T            !   if any switches        !
  1675.             ET&64"E        !     if not detached        !
  1676.                 :@^UF/    !       append create msg to F    !
  1677.                 @^A%Creating "%
  1678.                 :G*    !       append last filespec    !
  1679.                 @^A%"
  1680. %                    !       append "<CR><LF>    !
  1681.                 /    !       done loading F.str    !
  1682.             '        !     endif            !
  1683.         '            !   endif            !
  1684.         0,.K            !   kill output fn in buffer    !
  1685.     '                ! endif                !
  1686.  
  1687.     ! ------------------------------------------------------------- !
  1688.     ! Now, deal with an input filename.  If the filename doesn't    !
  1689.     ! have a filetype, first we'll try .TES; and, if there is no    !
  1690.     ! .TES file, we'll try .TEC.  Once we have an input filename,    !
  1691.     ! we'll ER it.                            !
  1692.     ! ------------------------------------------------------------- !
  1693.  
  1694.     J                ! jump to start of buf        !
  1695.     :@S%.%"U            ! if no ".", no filetype    !
  1696.         ZJ            !   jump to buf end        !
  1697.         @I%.TES%        !   insert ".TES"        !
  1698.         HXQ            !   put input fn in Q.str    !
  1699.         :@ER%^EQQ%"U        !   if ".TES" doesn't exist    !
  1700.             -@FS%.TES%.TEC%    !     try ".TEC"        !
  1701.         '            !   endif            !
  1702.     '                ! endif                !
  1703.     HXQ                ! Q.str = input filename    !
  1704.     HK                ! kill buffer            !
  1705.     @ER%^EQQ%            ! open input file        !
  1706.     QB"T                ! if any switches        !
  1707.         ET&64"E            !   if not detached        !
  1708.             @^A%Squishing "%!     display squish message"    !
  1709.             :G*        !     display filespec buffer    !
  1710.             @^A%"
  1711. %                    !     display "<CR><LF>        !
  1712.         '            !   endif            !
  1713.     '                ! endif                !
  1714.  
  1715.     ! ------------------------------------------------------------- !
  1716.     ! If there's no output filename, we'll stay in TECO after    !
  1717.     ! squishing the input file.  If there is an output file, we'll    !
  1718.     ! exit TECO after squishing.                    !
  1719.     ! ------------------------------------------------------------- !
  1720.  
  1721.     :QF"E                ! if no output filename        !
  1722.         Y            !   yank 1st page        !
  1723.         128,0ET            !   turn off abort-on-error    !
  1724.         <            ! ----loop begin--------------- !
  1725.             ^E"T        !     if formfeed flag        !
  1726.                 ZJ    !       jump to buf end        !
  1727.                 12@I%%    !       insert <FF>        !
  1728.             '        !     endif            !
  1729.             :A;        !     break if append fails    !
  1730.         >            ! ----loop end----------------- !
  1731.         MA            !   squeeze page        !
  1732.         MP            !   ??? what's in Q-reg P ???    !
  1733.     |                ! else (we have an output fn)    !
  1734.         Y            !   yank 1st page        !
  1735.         QB"F            !   if no switches        !
  1736.             128,0ET        !     turn off abort-on-error    !
  1737.         '            !   endif            !
  1738.  
  1739.         ! ----------------------------------------------------- !
  1740.         ! if we're at end-of-file after yanking in the first    !
  1741.         ! page, then squeeze what we've read in and write it    !
  1742.         ! out.  If we're not at end-of-file, then we'll have    !
  1743.         ! to go into a loop: squeezing the page we have, and    !
  1744.         ! then reading in the next page.            !
  1745.         ! ----------------------------------------------------- !
  1746.  
  1747.         ^N"T            !   if at end-of-file        !
  1748.             ^E"T        !     if formfeed flag        !
  1749.                 ZJ    !       jump to buf end        !
  1750.                 12@I%%    !       insert <FF>        !
  1751.             '        !     endif            !
  1752.             MA        !     squeeze page        !
  1753.             MF        !     open output file        !
  1754.             HPW        !     write page        !
  1755.             HK        !     kill page            !
  1756.         |            !   else            !
  1757.             MF        !     open output file        !
  1758.             <        ! ------loop begin------------- !
  1759.             ^E"T        !     if formfeed flag        !
  1760.                 ZJ    !       jump to buf end        !
  1761.                 12@I%%    !       insert <FF>        !
  1762.             '        !     endif            !
  1763.             MA        !     squeeze current page    !
  1764.             HPW        !     write current page    !
  1765.             HK        !     kill current page        !
  1766.             :Y;        !     break if yank fails    !
  1767.             >        ! ------loop end--------------- !
  1768.         '            !   endif            !
  1769.         EF            !   close output file        !
  1770.         EX            !   exit            !
  1771.     '                !   endif            !
  1772. '                    ! endif                !
  1773.